<template>
	
	<div style="height: 100%;">
		<ArtTableHeader v-model:columns="columnChecks" @refresh="handleRefresh">
		  <template #left>
			  <div style="display: flex;">
				  <ArtButtonTable  v-for="btn in customToolBars" v-bind="btn"></ArtButtonTable>
			  </div>
		  </template>
		</ArtTableHeader>
		
		<ArtTable
		  ref="tableRef"
		  height=" calc(100% - 0px)"
		  :row-key="rowKey"
		  :loading="loading"
		  :data="tableData"
		  :currentPage="pagination.currentPage"
		  :pageSize="pagination.pageSize"
		  :total="total"
		  :marginTop="10"
		  :pagination="isPagination"
		  :hideOnSinglePage="hideOnSinglePage"
		  :paginationAlign="props.paginationAlign"
		  @selection-change="handleSelectionChange"
		  @size-change="handleSizeChange"
		  @current-change="handleCurrentChange"
		>
		  <template v-for="col in columns" :key="col.prop || col.type" >
				<ElTableColumn  
					 v-bind="col" 
					:sort-orders="['ascending', 'descending']"
					:formatter="getFormatter(col)"
				 />
		  </template>
		</ArtTable>
	</div>
</template>

<script setup lang="ts">
import { computed, ref, watch, shallowRef, onMounted } from 'vue';
import { useWindowSize } from '@vueuse/core';
import { storeToRefs } from 'pinia';
import { useTableStore } from '@/store/modules/table';
import { useDictStore } from '@/store/modules/dict';
import dayjs from 'dayjs';
import { RuleService } from '@/api/data-rule/ruleApi';
import { Loading } from '@element-plus/icons-vue';
import { number } from 'echarts';
import { useCheckedColumns } from '@/composables/useCheckedColumns'
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
const { width } = useWindowSize();
const dictStore = useDictStore();
const loading = ref(false)
import { $t } from '@/locales'
const emit = defineEmits([
  'update:currentPage',
  'update:pageSize',
  'update:total',
  'row-click',
  'size-change',
  'current-change',
  'selection-change',
  'sort-change',
  'reload',
  'loading',
  'update:data',
]);

interface TableProps {
	/** 表格数据源 */
	rule: string
    /** 表格数据源 */
    data?: any[]
    /** 是否显示加载状态 */
    loading?: boolean
    /** 行数据的 Key，用于标识每一行数据 */
    rowKey?: string
    /** 是否显示边框 */
    border?: boolean | null
    /** 是否使用斑马纹样式 */
    stripe?: boolean | null
    /** 是否显示序号列 */
    index?: boolean
    /** 表格高度，可以是数字或 CSS 值 */
    height?: string | number
    /** 表格最大高度，可以是数字或 CSS 值 */
    maxHeight?: string | number
    /** 是否显示表头 */
    showHeader?: boolean
    /** 是否高亮当前行 */
    highlightCurrentRow?: boolean
    /** 空数据时显示的文本 */
    emptyText?: string
    /** 是否显示分页 */
    pagination?: boolean
    /** 总条目数 */
    total?: number
    /** 当前页码 */
    currentPage?: number
    /** 每页显示条目个数 */
    pageSize?: number
    /** 每页显示个数选择器的选项列表 */
    pageSizes?: number[]
    /** 只有一页时是否隐藏分页器 */
    hideOnSinglePage?: boolean
    /** 分页器的对齐方式 */
    paginationAlign?: 'left' | 'center' | 'right'
    /** 分页器的大小 */
    paginationSize?: 'small' | 'default' | 'large'
    /** 分页器的布局 */
    paginationLayout?: string
    /** 是否显示表头背景色 */
    showHeaderBackground?: boolean | null
    /** 表格距离顶部距离 */
    marginTop?: number
    /** 表格大小 */
    size?: 'small' | 'default' | 'large'
	fetchData?: (params?: any) => Promise<any>
	autoLoad?: boolean
	customFormatters?: Record<string, (value: any, row: any) => any>
	customToolBars?: Record<string, (value: any, row: any) => any>
	[key: string]: any
  }
  

  const props = withDefaults(defineProps<TableProps>(), {
    data: () => [],
    loading: false,
	rule:'',
    rowKey: 'id',
    border: null,
    stripe: null,
    index: false,
    height: '100%',
    showHeader: true,
    highlightCurrentRow: false,
    emptyText: '暂无数据',
    pagination: true,
    total: 0,
    currentPage: 1,
    pageSize: 20,
    hideOnSinglePage: true,
    pageSizes: () => [10, 20, 30, 50],
    paginationAlign: 'center',
    paginationSize: 'default',
    paginationLayout: '',
    showHeaderBackground: null,
    marginTop: 20,
	fetchData:  ()  => Promise.resolve({}),
	autoLoad: true,
	customFormatters: () => ({}),
	customToolBars: () => ({})
  })

const SELECTION_KEY = '__selection__'
const EXPAND_KEY = '__expand__'
const INDEX_KEY = '__index__'

const DEFAULT_PLACEHOLDER = '-';
const total = ref<number>(0);
const tableData=ref<any[]>([]);
const selectedRows = ref<any[]>([])
const handleSelectionChange = (selection: any) => {
  emit('selection-change', selection);
  selectedRows.value = selection
};

const pagination = reactive({
	currentPage: 1,
	pageSize: 20,
})

const handleSizeChange = (newPageSize: number) => {
	pagination.pageSize = newPageSize
	loadData()
}

const handleCurrentChange = (newCurrentPage: number) => {
	pagination.currentPage = newCurrentPage
	loadData()
}


// 统一格式化函数
const getFormatter = (col: any) => {
  // 优先使用自定义格式化函数
  if (props.customFormatters[col.name!]) {
	return (row: any) => props.customFormatters[col.name!](row[col.name!], row)
  }
  
  // 日期格式化
  if (col.dataType === 'Date' && col.displayFormat) {
	return (row: any) => 
	  row[col.name!] ? dayjs(row[col.name!]).format(col.displayFormat) : DEFAULT_PLACEHOLDER
  }
  
  // 常量映射
  if (col.mapping === 'const' && col.mappingInfo) {
	try {
	  const mapping = JSON.parse(col.mappingInfo)
	  return (row: any) => {
		const value = row[col.name!] ?? ''
		return mapping[String(value)] || DEFAULT_PLACEHOLDER
	  }
	} catch (e) {
	  console.error('常量映射解析错误:', e)
	  return () => DEFAULT_PLACEHOLDER
	}
  }
  
  // 字典映射
  if (col.mapping === 'dict' && col.mappingKey) {
	return (row: any) => {
	  const value = row[col.name!] ?? ''
	  return dictStore.getDictMappingValue(col.mappingKey!, String(value)) || DEFAULT_PLACEHOLDER
	}
  }
  
  return (row: any) => {
	  return col.name.split('.').reduce((acc: { [x: string]: any; } | null | undefined, part: string | number) => {
	    if (acc === null || acc === undefined) return undefined;
	    return acc[part];
	  }, row);
  }
}


const isPagination=ref<boolean>();
const {allColumns, columnChecks, columns,resetColumns} = useCheckedColumns(() => []);
// 加载列配置
const fetchColumns = async () => {
  // 验证规则是否存在
  if (!props.rule) {
    console.warn('未提供规则名称，无法加载列配置');
    return;
  }
  try {
    const { rule,fields } = await RuleService.getColumns(props.rule);
	
	// 验证响应数据
	if (!Array.isArray(fields)) {
	  throw new Error('返回的字段配置不是数组格式');
	}
	resetColumns();
	isPagination.value = rule.pagination === '0';
	for(var col of fields){
		allColumns.push({
			id:col.id,
			type:getColumnType(col.name),
			prop: col.name,
			align:col.align,
			label: col.label,
			width: col.width==0 ? 'auto':  col.width,
			fixed: col.fixed =='left' ||col.fixed =='right' ? col.fixed:false ,
			sortable: col.sortable=='0',
			mappingInfo:col.mappingInfo,
			mapping:col.mapping,
			dataType:col.dataType,
			displayFormat:col.displayFormat,
			mappingKey:col.mappingKey,
			name:col.name,
			checked: col.isVisible=='0'
		})
		
		if (col.name === 'selection') {
		  columnChecks.value.push({
		    prop: SELECTION_KEY,
		    label: $t('table.column.selection'),
		    checked: col.isVisible=='0'
		  })
		} else if (col.name === 'expand') {
		  columnChecks.value.push({
		    prop: EXPAND_KEY,
		    label: $t('table.column.expand'),
		    checked: col.isVisible=='0'
		  })
		} else if (col.name === 'index') {
		  columnChecks.value.push({
		    prop: INDEX_KEY,
		    label: $t('table.column.index'),
		    checked: col.isVisible=='0'
		  })
		} else {
		  columnChecks.value.push({
			prop: col.name,
			label: col.label,
			checked: col.isVisible=='0'
		  })
		}
	}
  } catch (error) {
    console.error('列配置加载失败', error);
  }
};

const getColumnType=(type: string) => {
	if('selection'==type){
		return 'selection'
	}
	if('index'==type){
		return 'index'
	}
	
	if('expand'==type){
		return 'expand'
	}
	return undefined;
}

const removeDotToCamelCase=(str: string): string => {
  // 如果输入不是字符串，直接返回原值
  if (typeof str !== 'string') return str;
  // 使用正则表达式匹配点及其后的字符
  return str.replace(/\.(\w)/g, (_, char) => char.toUpperCase());
}

// 加载表格数据
const loadData = async () => {
	loading.value = true;
	emit('loading', true);
	try {
		if(isPagination.value==true){
			const { list, totalRow } = await props.fetchData()
			tableData.value=list;
			total.value=totalRow
		}
		else{
			const data = await props.fetchData();
			tableData.value=data;
			emit('update:data', data);
		}
	} catch (error) {
		console.error('数据加载失败', error);
		tableData.value=[];
		emit('update:data', []);
	} finally {
		loading.value = false;
		emit('loading', false);
	}
};


const handleRefresh = () => {
	loadData()
}

// 重新加载数据
const reload = () => {
	loadData();
};

const reset = () => {
	if(isPagination.value==true) {
		pagination.currentPage=1
	};
	loadData();
};

const search = () => {
	if(isPagination.value==true) {
		pagination.currentPage=1
	};
	loadData();
};

const pageNumber = computed({
  get: () => pagination.currentPage,
  set: () => {
  }
})

const pageSize = computed({
  get: () => pagination.pageSize,
  set: () => {
  }
})

const selections = computed({
  get: () => selectedRows.value,
  set: () => {
  }
})

// 暴露方法给父组件
defineExpose({
  reload,
  search,
  reset,
  pageNumber,
  pageSize,
  selections
});

onMounted(async () => {
  await fetchColumns();
  if (props.autoLoad) {
	loadData();
  }
});

</script>


<style lang="scss" scoped>
	
  .art-table {
	  
	 --table-border-color: var(--el-table-border-color);
	 
    .table-container {
      height: 100%;
    }
	
    .table-pagination {
      display: flex;
      margin-top: 8px;

      // 分页对齐方式
      &.left {
        justify-content: flex-start;
      }

      &.center {
        justify-content: center;
      }

      &.right {
        justify-content: flex-end;
      }
    }

    :deep(.el-table) {
      th.el-table__cell {
        font-weight: 600;
      }
    }

    &.header-background {
      :deep(.el-table) {
        th.el-table__cell {
          background-color: var(--el-fill-color-light);
        }
      }
    }
  }

  // 移动端分页
  @media (max-width: $device-phone) {
    :deep(.el-pagination) {
      display: flex;
      flex-wrap: wrap;
      gap: 15px 0;
      align-items: center;
      justify-content: center;

      .el-pagination__sizes {
        .el-select {
          width: 100px !important;

          .el-select__wrapper {
            height: 30px !important;
          }
        }
      }

      .el-pager {
        li {
          margin-right: 2px;
        }
      }

      .el-pagination__jump {
        margin-left: 5px;

        .el-input {
          height: 32px !important;
        }
      }
    }
  }
</style>